modCount 属性
在 AbstractCollection 中存在一个 modCount 属性:
1 | /** |
ConcurrentModificationException 和 fast-fail 机制
以 ArrayList 的 迭代器为例:
1 | public Iterator<E> iterator() { |
迭代器进行实例化时,迭代器 expectedModeCount 属性初始值是被迭代的集合中的 modCount。
在迭代器调用 next 和 remove 方法时,会统一调用 checkForComdification 方法,该方法会每次检查 expectedModeCount 和当前被迭代的集合中的 modCount 值是否相等,不相等即抛出 ConcurrentModificationException 异常。
即迭代的时候,为了防止有其他线程在并发操作集合时,采用了该机制来防止多线程安全问题的产生。
利用 modCount 属性,在可以修改集合结构的方法内修改 modCount 值,并且在迭代的时候不断检查。
而这正是 fast-fail 机制。
解决 fast-fail
fast-fail 机制是防止多线程问题的一种手段,那么要解决该问题,只要遵循多线程并发问题的解决方法即可。
- 涉及到 modCount 方法上加 synchronized 关键字
- 使用 Collections.synchronizedList
- 使用并发包下的 CopyOnWriteArrayList 替换 ArrayList
CopyOnWriteArrayList 是首选,后续有机会会分析 CopyOnWriteArrayList 如何避免 fast-fail 机制的原理。